/**
 * 
 */
package com.kgcx.coupon.service;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import javax.annotation.Resource;
import org.apache.commons.lang.StringUtils;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.kgcx.common.redis.JsonRedisTemplate;
import com.kgcx.coupon.domain.CouponDetail;
import com.kgcx.coupon.domain.PullConfig;
import com.kgcx.coupon.domain.PullRule;
import com.kgcx.coupon.domain.UserCoupon;
import com.kgcx.coupon.domain.UserPull;
import com.kgcx.coupon.domain.UserRelation;
import com.kgcx.coupon.mapper.UserPullMapper;
import com.kgcx.coupon.mapper.UserRelationMapper;

import lombok.extern.slf4j.Slf4j;

/**
 * @author qinze
 * 用户拉新服务
 *
 */
@Slf4j
@Service
public class UserPullNewService {
	
	@Resource
	private UserPullMapper userPullMapper; //老用户拉新次数
	@Resource
	private UserRelationMapper userRelationMapper;//新用户与老用户
	@Resource
	private PullConfigService pullConfigService;
	@Resource
	private PullRuleService pullRuleService;
	@Resource
	private UserCouponService userCouponService;
	@Resource
	private JsonRedisTemplate<Long> lock;
	@Resource
	private JsonRedisTemplate<String> strRedisTemplate;
	@Resource
	private CouponDetailService couponDetailService;
	/**
	 * 老用户锁 KEY
	 */
	private static final String LOCKKEY = "old:user:rule:";
	/**
	 * 老用户与新用户关系存入redis KEY
	 */
	private static final String MAPKEY = "user:pull:new:";
	/**
	 * 老用户拉新数计算	 KEY
	 */
	private static final String PULLNEWCOUNT = "pull:new:count:";
	
	/**
	 * 给拉新者赠送优惠（每次领用赠送）  登录到时候调用
	 * 
	 * @param userRelation
	 */
	@Transactional(rollbackFor = Exception.class)
	public void inserUserPullNew(UserRelation userRelation) {
		ValueOperations<String, Long> vOp = lock.opsForValue();
		//根据老用户ID锁1秒
		String key = LOCKKEY + userRelation.getUserId();
		if (vOp.setIfAbsent(key, 0L)) {
			vOp.getOperations().expire(key, 1, TimeUnit.SECONDS);
			String repeatKey = String.valueOf(userRelation.getCoverUserId()) + ":" + String.valueOf(userRelation.getUserId());
			String values = strRedisTemplate.opsForValue().get(repeatKey);
			if (null == values) {
				//把老用户与新用户关系存入redis
				strRedisTemplate.boundHashOps(MAPKEY).put(String.valueOf(userRelation.getCoverUserId()), userRelation);
				//拉新者赠送优惠(每次领用赠送)
				oldUserRule(userRelation.getUserId().intValue());
				// 新人赠送优惠(新人策略)
				newUserRule(userRelation.getCoverUserId().intValue());
				//将老用户与新用户关系执行过的存入redis，防止重复
				strRedisTemplate.opsForValue().set(repeatKey, "key");
			}
		}
	}
	
	/**
	 * 拉新者进行每次领用赠送
	 * @param userId 老用户ID
	 */
	public void oldUserRule(Integer userId) {
			PullConfig pullConfig = pullConfigService.selectPullConfig();
			if (null != pullConfig) {
				/**
				 * 每次领用赠送
				 */
				if (null != pullConfig.getCouponQty() && 0 < pullConfig.getCouponQty()) {
					for (int i = 0; i < pullConfig.getCouponQty(); i++) {
						UserCoupon userCoupon = new UserCoupon();
						userCoupon.setCouponId(pullConfig.getCouponId());
						userCoupon.setUserId(userId);
						userCoupon.setStatus(0);// 使用状态（0未使用1已使用）
						userCoupon.setCreateTime(new Date());
						userCouponService.insertUserCoupon(userCoupon);
						log.info("拉新者进行每次领用赠送,优惠卷ID = {}", pullConfig.getCouponId());
					}
				}
			}
		}
	
	/**
	 * 新人策略
	 *  @param userId 新用户ID
	 */
	public void newUserRule (Integer userId) {
		List<CouponDetail> couponDetailList = couponDetailService.selectNewStrategy();
		for (CouponDetail couponDetail : couponDetailList) {
			if (null != couponDetail.getCouponQty() && 0 < couponDetail.getCouponQty()) {
				for (int i = 0; i < couponDetail.getCouponQty(); i++) {
					UserCoupon userCoupon = new UserCoupon();
					userCoupon.setCouponId(couponDetail.getCouponId());
					userCoupon.setUserId(userId);
					userCoupon.setStatus(0);// 使用状态（0未使用1已使用）
					userCoupon.setCreateTime(new Date());
					userCouponService.insertUserCoupon(userCoupon);
					log.info("新人策略,优惠卷ID = {}", couponDetail.getCouponId());
				}
			}
		}
	}
	
	/**
	 * 累计拉新配置(老用户赠送优惠卷) 支付时候调用
	 * @param newUserId 新用户ID
	 */
	@Transactional(rollbackFor = Exception.class)
	public void accumulativePullNewConfig(Integer newUserId) {
		log.info("支付完成执行老用户累计拉新配置 = {}", newUserId);
		UserRelation userRelation = (UserRelation) strRedisTemplate.boundHashOps(MAPKEY).get(String.valueOf(newUserId));
		if (null != userRelation) {
			//新增新用户与老用户关系
			userRelationMapper.insert(userRelation);
			//将老用户做key计数拉新值
			Long pullNewCount = strRedisTemplate.opsForValue().increment(PULLNEWCOUNT + userRelation.getUserId(), 1L);
			log.info("老用户userId = {},拉新数 = {}", userRelation.getUserId(), pullNewCount);
			// 拉新者进行每次领用赠送
			Integer userId = userRelation.getUserId().intValue();//老用户ID
			PullConfig pullConfig = pullConfigService.selectPullConfig();
			if (null != pullConfig) {
				if (1 == pullConfig.getStrategyStatus()) {
					// 获取拉新者策略
					List<PullRule> ruleList = pullRuleService.selectPullRuleByConfigId(pullConfig.getKid());
					// 获取当前老用户拉新数
					//UserPull userPull = userPullMapper.selectByPrimaryKey(Long.parseLong(String.valueOf(userId)));
					if (null != pullNewCount) {
						for (PullRule pullRule : ruleList) {
							log.info("老用户拉新值 = {},优惠卷需要拉新值 = {},优惠卷张数 = {}", pullNewCount.intValue(),pullRule.getPullTotal(),pullRule.getCouponQty());
							if (pullNewCount.intValue() >= pullRule.getPullTotal()) {
								String key = String.valueOf(userId) + ":" + pullRule.getPullTotal();
								String values = strRedisTemplate.opsForValue().get(key);
								if (StringUtils.isBlank(values)) {
									for (int i = 0; i < pullRule.getCouponQty(); i++) {
										UserCoupon userCoupon = new UserCoupon();
										userCoupon.setCouponId(pullRule.getCouponId());
										userCoupon.setUserId(userId);
										userCoupon.setStatus(0);// 使用状态（0未使用1已使用）
										userCoupon.setCreateTime(new Date());
										userCouponService.insertUserCoupon(userCoupon);
										strRedisTemplate.opsForValue().set(key, "true");
									}
								}
							}
						}
						//更新老用户拉新次数
						UserPull userPullObj = new UserPull();
						userPullObj.setUserId(userRelation.getUserId());
						userPullObj.setPullQty(pullNewCount.intValue());//拉新数
						userPullMapper.insertOrUpdate(userPullObj);
						//删除redis新用户与老用户关系
						strRedisTemplate.boundHashOps(MAPKEY).delete((String.valueOf(newUserId)));
					}
				}
			}
		}
	}
}
